;(function(root, factory) {
	debugger;
	if (typeof define === 'function' && define.amd) {
		//AMD
		define(['jquery'], factory);
	} else if (typeof exports === 'object') {
		//Node, CommonJS之类的
		module.exports = factory(require('jquery'));
	} else {
		//浏览器全局变量(root 即 window)
		root.report = factory(window.jQuery || window.Zepto || window.$); // Zepto supported on browsers as well
	}

//this，在浏览器环境指window，在nodejs环境指global
//使用this而不直接用window/global是为了兼容浏览器端和服务端
//将this传进函数体，使全局变量变为局部变量，可缩短函数访问全局变量的时间
})(this, function($, s) {
	//开启严格模式，规范代码，提高浏览器运行效率
	'use strict';
	debugger;
	let report = {
		name: 'reportjs',
		version: '1.0.0',
		settings: {
			reportServer: '',//（可选）全局配置，在所有操作中未指定报表服务时，会调用此地址
			reportVersion: '9.0',//（可选）报表服务器版本，默认 9.0 ,目前支持 8.0 , 9.0
			showPrintTip: false,//（可选）是否显示打印提示信息，默认 false
			sessionIdName: 'data-report-session',//(可选)报表SessionID属性名称，默认“data-report-session”
			formIdPrefix: '#reportForm',//(可选)报表表单ID前缀，默认“#reportForm”
			formParamPrefix: '',//(可选)表单参数前缀，默认无,若此参数为空且表单参数含有前缀的话，内部处理器将不会处理，报表可能会无法访问
			frameIdPrefix: '#reportFrame',//(可选)报表表单ID前缀，默认“#reportFrame”
			reportletsSelectionIdPrefix: '#reportlets',//（可选）报表列表ID前缀，默认“#reportlets”
			showLog: false,//（可选）显示日志，默认 false
			serializeJSON: { checkboxUncheckedValue: 'false', parseBooleans: true }//（可选）表单序列化参数
		},
		options: undefined, //fn, 报表配置
		query: undefined, //fn, 查询报表
		preview: undefined, //fn, 预览报表
		print: undefined, //fn, 直接打印报表
		switch: undefined //fn, 切换报表
	};

	/**
	 * 报表参数去前缀
	 * @param params  {Object} params 请求参数对象
	 * @param paramPrefix 参数名前缀
	 */
	function trimPrefix (params, paramPrefix) {
		debugger;
		if (params && paramPrefix) {
			const map = {};
			Object.keys(params).map(key => {
				const value = params[key] ? params[key] : '';
				let trimKey = key;
				if (paramPrefix && key.match(`^${paramPrefix}`)) {
					trimKey = key.substring(paramPrefix.length);
				}
				map[trimKey] = value;
			});
			return map;
		}
		return params;
	}

	/**
	 * 获取Get请求详细地址
	 * @param {String} url 请求地址
	 * @param {Object} params 请求参数对象
	 * @param {string} paramPrefix 参数前缀
	 * @returns {String}
	 */
	function getUrl (url, params, paramPrefix) {
		let paramStr = '';
		debugger;
		const newParams = trimPrefix(params, paramPrefix);
		if (params) {
			Object.keys(newParams).map((key, index, array) => {
				const value = newParams[key] ? newParams[key] : '';
				if (index !== array.length - 1) {
					paramStr += `${key}=${value}&`;
				} else {
					paramStr += `${key}=${value}`;
				}
			});
		}
		return paramStr !== '' ? `${url}?${paramStr}` : url;
	}

	/**
	 * 报表表单下指定选择器值得修改
	 * @param selector Query 选择器
	 * @param value 新值
	 * @param idSelector 指定ID选择器下（可选）
	 */
	function changeValue (selector, value, idSelector) {
		debugger;
		if (idSelector) {
			idSelector.find(selector).val(value);
		} else {
			$(selector).val(value);
		}
	}

	/**
	 * 报表form jQuery选择器
	 * @param reportId
	 * @returns {*|jQuery|HTMLElement}
	 */
	function reportFormIdSelector (reportId) {
		return reportId ? $(report.settings.formIdPrefix + reportId) : $(report.settings.formIdPrefix);
	}

	/**
	 * 报表iframe jQuery选择器
	 * @param reportId
	 * @returns {*|jQuery|HTMLElement}
	 */
	function reportFrameIdSelector (reportId) {
		return reportId ? $(report.settings.frameIdPrefix + reportId) : $(report.settings.frameIdPrefix);
	}

	/**
	 * 表单数据序列化
	 * @param selector jQuery 选择器
	 * @returns {*|jQuery}
	 */
	function getFormData (selector) {
		debugger;
		const data = $(selector).serializeJSON(report.settings.serializeJSON);
		if (report.settings.showLog) {
			console.log(`表单数据序列化：${JSON.stringify(data)}`);
		}
		return data;
	}

	/**
	 * 根据报表表单序列化为查询参数
	 * @param {String} reportId 报表ID
	 * @returns {Object} map
	 */
	function serializeJSON4Form (reportId) {
		return getFormData(reportFormIdSelector(reportId));
	}

	/**
	 * 获取报表实际请求地址
	 * @param {String} reportServer 报表服务地址
	 * @param {Object} params 请求参数
	 * @param {string} paramPrefix 请求参数前缀
	 * @returns {String}
	 */
	const reportUrl = (reportServer, params, paramPrefix) => {
		if (reportServer) {
			return encodeURI(getUrl(reportServer, params, paramPrefix));
		}
		throw new Error('报表服务地址不能为空');
	};

	/**
	 * 获取报表 SessionID
	 * @param reportId 报表ID
	 * @returns {string}
	 */
	function getReportSession (reportId) {
		return reportFrameIdSelector(reportId).attr(report.settings.sessionIdName);
	}

	/**
	 * 设置报表SessionID
	 * @param {String} reportId 报表ID
	 * @param {String} reportServer 报表服务地址
	 * @param {Object} params 请求参数
	 * @returns {String}
	 */
	function setReportSession (reportId, reportServer, params) {
		// TODO: 2018/12/11 0011 16:07 校验查询条件发生变化才重新获取session
		debugger;
		let newParams = params;
		newParams.op = 'getSessionID';
		newParams = trimPrefix(newParams, report.settings.formParamPrefix);
		// 8.0 报表 session 获取
		if (report.settings.reportVersion === '8.0') {
			debugger;
			const sessionUrl = reportUrl(reportServer, params, report.settings.formParamPrefix);
			let reportSessionID;
			$.get(sessionUrl, res => {
				reportSessionID = res;
				if (reportSessionID) {
					if (report.settings.showLog) {
						console.log(`报表SessionID：${reportSessionID}`);
					}
					reportFrameIdSelector(reportId).attr(report.settings.sessionIdName, reportSessionID);
				} else {
					throw new Error('获取报表sessionID失败，报表扩展功能将无法使用，请联系相关技术人员');
				}
			});
		}
		// 9.0 报表 Session 获取
		if (report.settings.reportVersion === '9.0') {
			$.getJSON(`${reportServer}?callback=?`, newParams, res => {
				debugger;
				const sessionID = res.sessionID || res.responseText || res;
				if (sessionID) {
					debugger;
					if (report.settings.showLog) {
						console.log(`报表SessionID：${sessionID}`);
					}
					reportFrameIdSelector(reportId).attr(report.settings.sessionIdName, sessionID);
				} else {
					throw new Error('获取报表sessionID失败，报表扩展功能将无法使用，请联系相关技术人员');
				}
			});
		}
	}

	/**
	 * 根据报表表单 id,报表服务地址 查询报表内容
	 * @param {String} reportId 报表ID
	 * @param {String} reportServer 报表服务地址
	 */
	function reportQuery (reportId, reportServer) {
		if (!reportServer) {
			throw new Error('报表服务地址不能为空');
		}
		debugger;
		const params = serializeJSON4Form(reportId);
		debugger;
		const url = reportUrl(reportServer, params, report.settings.formParamPrefix);
		if (report.settings.showLog) {
			console.log(`报表实际访问地址：${url}`);
		}
		debugger;
		setReportSession(reportId, reportServer, params);
		reportFrameIdSelector(reportId)
			.attr('src', url)
			.addClass('bg-color');
	}

	/**
	 * 根据报表ID 执行报表
	 * @param {String} reportId 报表ID
	 * @param {String} reportServer 报表服务地址
	 * @param {boolean} quietPrint 是否静默打印
	 */
	function reportPrintOperation (reportId, reportServer, quietPrint = true) {
		// TODO: 2019/5/23 16:17
	}

	/**
	 * 报表配置项
	 * @param config
	 */
	report.options = function(config) {
		debugger;
		if (config) {
			if (config.reportServer) {
				report.settings.reportServer = config.reportServer;
			}
			if (config.reportVersion) {
				report.settings.reportVersion = config.reportVersion;
			}
			if (config.showPrintTip) {
				report.settings.showPrintTip = config.showPrintTip;
			}
			if (config.sessionIdName) {
				report.settings.sessionIdName = config.sessionIdName;
			}
			if (config.formIdPrefix) {
				report.settings.formIdPrefix = config.formIdPrefix;
			}
			if (config.formParamPrefix) {
				report.settings.formParamPrefix = config.formParamPrefix;
			}
			if (config.frameIdPrefix) {
				report.settings.frameIdPrefix = config.frameIdPrefix;
			}
			if (config.showLog) {
				report.settings.showLog = config.showLog;
			}
			if (config.serializeJSON) {
				report.settings.serializeJSON = config.serializeJSON;
			}
		}
	};

	/**
	 * 根据报表表单 id,报表服务地址 查询报表内容
	 * @param {String} reportId 报表ID
	 * @param {String} reportServer 报表服务地址
	 */
	report.query = function(reportId, reportServer = null) {
		debugger;
		let logInfo = `报表ID：${reportId} 报表服务地址`;
		if (reportServer) {
			logInfo += `（局部）：${reportServer}`;
			reportQuery(reportId, reportServer);
		} else {
			logInfo += `（全局）：${report.settings.reportServer}`;
			reportQuery(reportId, report.settings.reportServer);
		}
		if (report.settings.showLog) {
			console.log(logInfo);
		}
	};

	/**
	 * 报表设置预览
	 * @param reportId 报表ID
	 * @param reportServer 报表服务地址(可选)，无时获取全局配置
	 * @see reportPreview
	 */
	report.preview = function(reportId, reportServer = null) {
		debugger;
		if (reportServer) {
			reportPrintOperation(reportId, reportServer, false);
		} else {
			reportPrintOperation(reportId, report.settings.reportServer, false);
		}
	};

	/**
	 * 打印报表
	 * @param {String} reportId 报表ID
	 * @param {String} reportServer 报表服务地址(可选)，无时获取全局配置
	 * @see reportPrint
	 */
	report.print = function(reportId, reportServer = null) {
		debugger;
		if (reportServer) {
			reportPrintOperation(reportId, reportServer);
		} else {
			reportPrintOperation(reportId, report.settings.reportServer);
		}
	};

	/**
	 *
	 * @param reportId 报表ID
	 * @param reportlet 切换后报表的名称
	 * @see changeValue
	 */
	report.switch = function(reportId, reportlet) {
		changeValue('input[name$=\'reportlet\']', reportlet, reportFormIdSelector(reportId));
		// 切换报表是清除 session
		reportFrameIdSelector(reportId).removeAttr(report.settings.sessionIdName);
	};

	return report;
});
